import json

from common.common_fun import initData
# from algorithm.geneticAlgorithm.Genetic import GeneticSolver
from algorithm.geneticAlgorithm.Genetic2.GeneticSolver import GeneticSolver


def genetic_result(data):
    (dim_n, dim_k, dim_c, start_node, goal_node, is_key, edges, cost_v, cost_e,
     node_index_dict, node_edge_dict) = initData(data)
    cost_e = [[inner_element[0] for inner_element in sublist] for sublist in cost_e]
    # print(cost_e)
    packNum = 5
    maxGen = 100
    Hayflick = 4
    mutationP = 0.04
    crossP = 0.7
    solver = GeneticSolver(start_node=start_node,goal_node=goal_node, is_key=is_key, cost_e=cost_e,
                           packNum=packNum, maxGen=maxGen, Hayflick=Hayflick, mutationP=mutationP, crossP=crossP)
    solver.run()
    result = solver.get_best_path()
    # print(result)
    path_node = [node_index_dict.get(node) for node in result]
    path_edge = list()
    for i in range(len(result) - 1):
        path_edge.append(node_edge_dict[(result[i], result[i + 1])])
    return path_node, path_edge


def genetic_display(data):
    # cost_e = [[inner_element[0] for inner_element in sublist] for sublist in cost_e]
    # 初始化数据
    (dim_n, dim_k, dim_c, start_node, goal_node, is_key, edges, cost_v, cost_e,
     node_index_dict, node_edge_dict) = initData(data)
    cost_e = [[inner_element for inner_element in sublist] for sublist in cost_e]

    pack_num = int(data["packNum"])
    max_gen = int(data["maxGen"])
    hay_flick = 4
    mutation_P = float(data["mutationP"])
    cross_P = float(data["crossP"])
    solver = GeneticSolver(start_node, goal_node, is_key, cost_e, pack_num, max_gen, hay_flick, mutation_P, cross_P)
    solver.run()
    display_data = solver.get_display_data()
    # print("")
    # print(json.dumps(display_data))
    display_map = dict()
    display_map["pathMap"] = dict()
    # print(display_data[0])
    for key1 in display_data[0].keys():
        node1 = node_index_dict.get(key1)
        display_map["pathMap"][node1] = dict()
        for key2 in display_data[0][key1].keys():
            node2 = node_index_dict.get(key2)
            display_map["pathMap"][node1][node2] = list()
            for i in range(len(display_data[0][key1][key2]) - 1):
                display_map["pathMap"][node1][node2].append(
                    node_edge_dict[(display_data[0][key1][key2][i], display_data[0][key1][key2][i + 1])])
    # print(display_map["pathMap"])
    display_map["displayData"] = list()
    i = 1
    for iter_data in display_data[1]:
        # if i == 1:
        #     # print(iter_data)
        #     print(iter_data['actions'][0])

        display_uint = dict()
        display_uint["gen"] = iter_data["gen"]
        display_uint["pack"] = [
            {"sum": u["sum"], "F": u["F"], "P": u["P"], "path": [node_index_dict.get(p) for p in u["path"]]} for u in iter_data["pack"][0]
        ]
        display_uint["action"] = [
            {
                "packId": u[2],
                "cross": {
                    "packId": u[0][0],
                    "isCross": u[0][1],
                    "crossP": u[0][2],
                    "selectedP": u[0][3],
                    "crossData": {
                        "fatherId": u[0][4][0],
                        "fatherCrossDNA": [node_index_dict.get(j) for j in u[0][4][1]],
                        "motherId": u[0][4][2],
                        "motherCrossDNA": [node_index_dict.get(j) for j in u[0][4][3]],
                        "childDNA": [node_index_dict.get(j) for j in u[0][4][4]]
                    },
                    "crossParents": u[0][5],
                },
                "mutate": {
                    "packId": u[1][0],
                    "isMutate": u[1][1],
                    "mutateP": u[1][2],
                    "mutateData": {
                        "packId": u[1][3][0],
                        "upDNA": [node_index_dict.get(j) for j in u[1][3][1]],
                        "downDNA": [node_index_dict.get(j) for j in u[1][3][2]],
                        "endDNA": [node_index_dict.get(j) for j in u[1][3][3]],
                    }
                }
            }
            for u in iter_data["actions"]
        ]
        # display_uint = dict()
        # display_uint["gen"] = iter_data[0]
        # display_uint["pack"] = [
        #     {"sum": u[0], "F": u[1], "P": u[2], "path": [node_index_dict.get(p) for p in u[3]]} for u in iter_data[1]
        # ]
        # display_uint["action"] = [
        #     {
        #         "packId": u[2],
        #         "cross": {
        #             "packId": u[0][0],
        #             "isCross": u[0][1],
        #             "crossP": u[0][2],
        #             "selectedP": u[0][3],
        #             "crossData": {
        #                 "fatherId": u[0][4][0],
        #                 "fatherCrossDNA": [node_index_dict.get(j) for j in u[0][4][1]],
        #                 "motherId": u[0][4][2],
        #                 "motherCrossDNA": [node_index_dict.get(j) for j in u[0][4][3]],
        #                 "childDNA": [node_index_dict.get(j) for j in u[0][4][4]]
        #             }
        #         },
        #         "mutate": {
        #             "packId": u[1][0],
        #             "isMutate": u[1][1],
        #             "mutateP": u[1][2],
        #             "mutateData": {
        #                 "packId": u[1][3][0],
        #                 "upDNA": [node_index_dict.get(j) for j in u[1][3][1]],
        #                 "downDNA": [node_index_dict.get(j) for j in u[1][3][2]],
        #                 "endDNA": [node_index_dict.get(j) for j in u[1][3][3]],
        #             }
        #         }
        #     }
        #     for u in iter_data[2]
        # ]
        display_map["displayData"].append(display_uint)
    # print(json.dumps(display_map))
    return display_map
